#import <SpringBoard/SBApplication.h>
#import <SpringBoard/SBApplicationController.h>
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#import <objc/runtime.h>
#import <UIKit/UIApplication.h>
#import <LockInfo/Plugin.h>

#import "FWCommon.h"
#import "FWListView.h"
#import "FWDotView.h"
#import "FWApplication.h"
#import "FWIconDotView.h"
#import "FWRoundedLabel.h"


CGFloat const kFWListViewDotSize = 9;
CGFloat const kFWListViewMarkerSpace = 18;
CGFloat const kFWListViewMarkerSize = 16;
CGFloat const kFWListViewDetailMargin = 22;
CGFloat const kFWListViewSeparatorSize = 4;
CGFloat const kFWListViewMarkerInset = 0;


@implementation FWListView

@synthesize dot, summaryText, detailText, detailTextAlternate, highlightText, flags, singleLine, expandSingleLine;


// ******************************************************************************************
#pragma mark -
#pragma mark Initialisation and object management

- (id)initWithFrame:(CGRect)frame table:(LITableView *)table
{
    if (self = [super initWithFrame:frame]) {
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        self.contentMode = UIViewContentModeRedraw;
        self.autoresizesSubviews = YES;
        self.backgroundColor = [UIColor clearColor];
        
        self.dot = [[[FWDotView alloc] initWithFrame:CGRectMake(4, 0, kFWListViewDotSize, kFWListViewDotSize)] autorelease];
        self.dot.backgroundColor = [UIColor clearColor];
        
        self.summaryText = [table labelWithFrame:CGRectZero];
        self.summaryText.frame = CGRectZero;
        self.summaryText.autoresizingMask = UIViewAutoresizingNone;
        self.summaryText.backgroundColor = [UIColor clearColor];
        //self.summaryText.backgroundColor = [UIColor yellowColor];
        
        self.detailText = [table labelWithFrame:CGRectZero];
        self.detailText.frame = CGRectZero;
        self.detailText.autoresizingMask = UIViewAutoresizingNone;
        self.detailText.backgroundColor = [UIColor clearColor];
        //self.detailText.backgroundColor = [UIColor yellowColor];
        
        self.highlightText =  [[[FWRoundedLabel alloc] initWithFrame:CGRectZero] autorelease];
        //self.highlightText.frame = CGRectZero;
        //self.highlightText.autoresizingMask = UIViewAutoresizingNone;
        //self.highlightText.backgroundColor = [UIColor clearColor];
        //self.highlightText.backgroundColor = [UIColor yellowColor];
        
        [self addSubview:self.dot];
        [self addSubview:self.summaryText];
        [self addSubview:self.detailText];
        [self addSubview:self.highlightText];
    }
    
    return self;
}

-(void)dealloc
{
    [dot release];
    [summaryText release];
    [detailText release];
    [detailTextAlternate release];
    [highlightText release];
    [flags release];
    
    [super dealloc];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Row height support

+ (CGFloat)heightOfSummaryRowWithFont:(UIFont*)font withFollowingRow:(BOOL)following
{
    CGFloat height = font.leading;
    
    // If no following line and the text area is smaller than the marker, use the marker size
    if (!following && (height < kFWListViewMarkerSpace))
        height = kFWListViewMarkerSpace;
    
    if (!following)
        ++height;
    
    return height;
}

+ (CGFloat)heightOfDetailRowWithFont:(UIFont*)font
{
    CGFloat height = font.leading;
    return height;
}


// ******************************************************************************************
#pragma mark -
#pragma mark Layout support

- (void)layoutSummaryRow:(CGRect)rect
{
    if (!self.dot.hidden) {
        // Place the dot half way up the title line
        CGRect dotRect = self.dot.frame;
        CGFloat pos = (rect.size.height - dotRect.size.height) / 2;
        if (pos < 0)
            pos = 0;
        
        self.dot.frame = CGRectMake(rect.origin.x + dotRect.origin.x,
                                    rect.origin.y + pos,
                                    dotRect.size.width,
                                    dotRect.size.height);
    }

    CGFloat rightMargin = rect.size.width - kFWListViewSeparatorSize;

    // Get the space we will be using for markers
    CGFloat flagHeight = rect.size.height;
    if (flagHeight < kFWListViewMarkerSpace)
        flagHeight = kFWListViewMarkerSpace;
    
    for (UIView* flag in self.flags) {
        if (!flag.hidden) {
            // Put action half way up the name line unless it is too small
            CGRect flagRect = flag.frame;
            CGFloat pos = (flagHeight - flagRect.size.height) / 2;
            if (pos < 0)
                pos = 0;

            flagRect = CGRectMake(rect.origin.x + rightMargin - flagRect.size.width,
                                  rect.origin.y + pos,
                                  flagRect.size.width,
                                  flagRect.size.height);
            rightMargin = rightMargin - flagRect.size.width - kFWListViewSeparatorSize;
            flag.frame = flagRect;
        }
    }
    
    CGRect summaryRect = CGRectMake(rect.origin.x + kFWListViewDetailMargin,
                                    rect.origin.y,
                                    rightMargin - kFWListViewDetailMargin,
                                    rect.size.height);
    self.summaryText.frame = summaryRect;
    
    // LILabel seems to stretch its text on rotation unless we do this
    [self.summaryText setNeedsDisplay];
}

- (void)layoutDetailRow:(CGRect)rect
{
    CGFloat leftMargin = rect.origin.x;
    CGFloat rightMargin = rect.origin.x + rect.size.width;
    
    // If we have a highlight string then try to allow that as much room as it needs
    if (!self.highlightText.hidden) {
        CGFloat priorityWidth = [self.highlightText sizeForHeight:rect.size.height].width;
        CGFloat dueWidth = [self.detailText.text sizeWithFont:self.detailText.style.font].width;
        
        // Is the line too long?
        if ((leftMargin + priorityWidth + kFWListViewSeparatorSize + dueWidth) > rightMargin) {
            if (self.detailTextAlternate) {
                CGFloat shortWidth = [self.detailTextAlternate sizeWithFont:self.detailText.style.font].width;
                if (shortWidth < dueWidth) {
                    self.detailText.text = self.detailTextAlternate;
                    dueWidth = shortWidth;
                }
            }				
            
            if ((leftMargin + priorityWidth + kFWListViewSeparatorSize + dueWidth) > rightMargin)
                priorityWidth = rightMargin - leftMargin - kFWListViewSeparatorSize - dueWidth;
        }
        
        CGRect highlightRect = CGRectMake(leftMargin, rect.origin.y, priorityWidth, rect.size.height);
        leftMargin += highlightRect.size.width + kFWListViewSeparatorSize;
        self.highlightText.frame = highlightRect;
        
        // LILabel seems to stretch its text on rotation unless we do this
        [self.highlightText setNeedsDisplay];
    }
    
    CGRect detailRect = CGRectMake(leftMargin, rect.origin.y, rightMargin - leftMargin, rect.size.height);
    self.detailText.frame = detailRect;
    
    // LILabel seems to stretch its text on rotation unless we do this
    [self.detailText setNeedsDisplay];
    
    // Redraw ourselves
    [self setNeedsDisplay];
}

- (void)layoutSubviews
{
    CGFloat summaryHeight = [FWListView heightOfSummaryRowWithFont:self.summaryText.style.font withFollowingRow:!singleLine];
    CGFloat detailHeight = [FWListView heightOfDetailRowWithFont:self.detailText.style.font];
    
    CGRect rect = self.superview.bounds;
    
    //NSLog(@"LI:FWTodo: Layout list view, frame {{%f, %f} {%f, %f}}", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);  

    CGRect detailRect, summaryRect;
    if (singleLine) {
        CGFloat offset = (summaryHeight - detailHeight) / 2;
        CGFloat width = rect.size.width * 0.6;

        if (expandSingleLine && self.detailText.hidden)
            width = rect.size.width;
        
        summaryRect = CGRectMake(0, 0, width, summaryHeight);
        detailRect = CGRectMake(width + kFWListViewSeparatorSize * 2, 
                                offset,
                                rect.size.width - width - kFWListViewSeparatorSize * 2,
                                detailHeight);
    }
    else {
        summaryRect = CGRectMake(0, 0, rect.size.width, summaryHeight);
        detailRect = CGRectMake(kFWListViewDetailMargin,
                                summaryHeight,
                                rect.size.width - kFWListViewDetailMargin,
                                detailHeight);
    }
    
    if (!self.detailText.hidden)
        [self layoutDetailRow:detailRect];
    
    [self layoutSummaryRow:summaryRect];
}

@end
